 #include"Task.hpp"
#include<string>
#include<vector>
 #include <unistd.h>
#include<cstdlib>
#include<cassert>

const int processnum = 10;  //10个进程
std::vector<task_t>  tasks ; //任务

//管道
class channel
{
  public:
    channel( int cmdcnt , pid_t slaverid  ,   const std::string  processname)
    :_cmdcnt(cmdcnt)
    ,_slaverid(slaverid)
    ,_processname(processname)
    {}

public:
  int _cmdfd;               // 发送任务的文件描述符
    pid_t _slaverid;          // 子进程的PID
    std::string _processname; // 子进程的名字 -- 方便我们打印日志
    int _cmdcnt;
};

//进程 

void Menu()
{
    std::cout << "################################################" << std::endl;
    std::cout << "# 1. 刷新日志             2. 刷新出来野怪        #" << std::endl;
    std::cout << "# 3. 检测软件是否更新      4. 更新用的血量和蓝量  #" << std::endl;
    std::cout << "#                         0. 退出               #" << std::endl;
    std::cout << "#################################################" << std::endl;
}


//子进程从读任务
void slaver()
{
  //从0文件描述符里读
 while(true)
 {
  int cmdcode  =0 ;
  ssize_t  n = read (  0,&cmdcode , sizeof(int)); 
//如果父进程不给子进程发送数据  , 父进程 阻塞等待
  //读取成功
  if( n == sizeof(int)) 
  {
 //执行cmdcode对应的任务列表
            std::cout <<"slaver say@ get a command: "<< getpid() << " : cmdcode: " <<  cmdcode << std::endl;
            //合法
       if(cmdcode >= 0 && cmdcode < tasks.size() ) 
      {
         tasks[cmdcode]() ;
      }
  } 
  //零表示文件结束
  if( n==0) 
  {
  break;
  }

}


} 


void Debug(const std::vector<channel> & channels)
{
    // test
    for(const auto &c :channels)
    {
        std::cout << c._cmdfd << " " << c._slaverid << " " << c._processname << std::endl;
    }
}

void InitProcessPool(std::vector<channel> * channels )
{
    // std::vector<int> oldfds;
  // 确保每一个子进程都只有一个写端
  for( int i =0 ; i<processnum ;i++)
  {
    //创建管道
      int pipefd[2] ={0};
      int n = pipe(pipefd);
    assert(!n);
   (void)n;

       pid_t id = fork(); 
       //父子进程通信,父进程写，子进程读
       if(id ==0 )
       {
        //child
   std::cout << "child: " << getpid() << " close history fd: ";
   //确保每一个子进程都只有一个写端
  // for(auto fd : oldfds)
  //  {
  //               std::cout << fd << " ";
  //               close(fd);
  //  }
        std::cout << "\n";

     //子进程关闭写端
     close(pipefd[1]);
    //重定向 ,0指向pipefd[0],指向读端
   dup2(pipefd[0], 0);
  

     slaver(); //执行子进程相关代码
      exit(0);
std::cout << "process : " << getpid() <<  std::endl;
       }
       //father 
      
     //父进程关闭读端
      close ( pipefd[0]);

      std::string name ="process-" + std::to_string(i) ; 
     // 添加channel字段了
      
     channels->push_back(channel(pipefd[1]  , id,name) ) ; 
    // oldfds.push_back(pipefd[1]);
     // sleep(1000);

  }
  

}

void ctrlSlaver(std::vector<channel> & channels  )

{
  //1. 选择任务




// 2. 选择进程
   //3. 发送任务
}

 int main()
 {
  LoadTask(&tasks);
  std::vector<channel>  channels;
  InitProcessPool(&channels);
 Debug(channels);
 //开始控制子进程
ctrlSlaver(channels);
    return 0 ;
 }